using System;
using System.Xml.Serialization;

namespace ElfBinary
{
	[Serializable]
	public class ElfHeader64
	{
		public ElfHeader64 ()
		{
		}

		[XmlElement]
		public ElfType 
		Type { 
			get { return  (ElfType)e_type; }
			set { e_type = (ushort)value; }
		}

		[XmlElement]
		public ElfMachine Machine {	
			get { 
				return (ElfMachine)e_machine; 
			}
			set {
				e_machine = (ushort)value;
			}
		}

		[XmlElement]
		public ElfVersion Version { 
			get { return (ElfVersion)e_version; } 
			set { e_version = (uint)value; }
		}

		[XmlElement]
		public ulong  EntryPointAddress { 
			get { return    e_entry; } 
			set { e_entry = value; }
		}

		[XmlElement]
		public ulong  ProgramHeaderFileOffset { 
			get{ return     e_phoff; }
			set { e_phoff = value; }
		}

		[XmlElement]
		public ulong   SectionHeaderFileOffset {
			get { return    e_shoff; }
			set { e_shoff = value; }
		}

		[XmlElement]
		public uint   ProcessorFlags { 
			get { return   e_flags; } 
			set { e_flags = value; }
		}

		[XmlElement]
		public ushort  ElfHeaderSize { 
			get { return     e_ehsize; }
			set { e_ehsize = value; }
		}

		[XmlElement]
		public ushort   ProgramHeaderRecordSize { 
			get { return    e_phentsize; }
			set { e_phentsize = value; }
		}

		[XmlElement]
		public ushort   ProgramHeaderEntryCount { 
			get { return   e_phnum; }
			set { e_phnum = value; }
		}

		[XmlElement]
		public ushort    SectionHeaderEntrySize {
			get { return   e_shentsize; }
			set { e_shentsize = value; }
		}

		[XmlElement]
		public ushort    SectionHeaderEntryCount { 
			get { return  e_shnum; }
			set { e_shnum = value; }
		}

		[XmlElement]
		public ushort    SectionHeaderStringEntryIndex { 
			get { return   e_shstrndx; }
			set { e_shstrndx = value; }
		}

		[XmlElement]
		public ElfIdentification Identity { get; set; }

		public void Read (System.IO.Stream s)
		{

			byte[] b = new byte[8];

			s.Read (b, 0, 2);
			e_type = BitConverter.ToUInt16 (b, 0);

			s.Read (b, 0, 2);
			e_machine = BitConverter.ToUInt16 (b, 0);

			s.Read (b, 0, 4);
			e_version = BitConverter.ToUInt32 (b, 0);

			s.Read (b, 0, 8);
			e_entry = BitConverter.ToUInt64 (b, 0);

			s.Read (b, 0, 8);
			e_phoff = BitConverter.ToUInt64 (b, 0);

			s.Read (b, 0, 8);
			e_shoff = BitConverter.ToUInt64 (b, 0);

			s.Read (b, 0, 4);
			e_flags = BitConverter.ToUInt32 (b, 0);

			s.Read (b, 0, 2);
			e_ehsize = BitConverter.ToUInt16 (b, 0);

			s.Read (b, 0, 2);
			e_phentsize = BitConverter.ToUInt16 (b, 0);

			s.Read (b, 0, 2);
			e_phnum = BitConverter.ToUInt16 (b, 0);

			s.Read (b, 0, 2);
			e_shentsize = BitConverter.ToUInt16 (b, 0);

			s.Read (b, 0, 2);
			e_shnum = BitConverter.ToUInt16 (b, 0);

			s.Read (b, 0, 2);
			e_shstrndx = BitConverter.ToUInt16 (b, 0);

		}

		ushort e_type;
		ushort e_machine;
		uint e_version;
		ulong e_entry;
		ulong e_phoff;
		ulong e_shoff;
		uint e_flags;
		ushort e_ehsize;
		ushort e_phentsize;
		ushort e_phnum;
		ushort e_shentsize;
		ushort e_shnum;
		ushort e_shstrndx;
	}
	//	64-Bit Data Types
	//
	//	Name 	Size 	Alignment 	Purpose
	//	Elf64_Addr 	8 	8 	Unsigned program address
	//	Elf64_Off 	8 	8 	Unsigned file offset
	//	Elf64_Half 	2 	2 	Unsigned medium integer
	//	Elf64_Word 	4 	4 	Unsigned integer
	//	Elf64_Sword 	4 	4 	Signed integer
	//	Elf64_Xword 	8 	8 	Unsigned long integer
	//	Elf64_Sxword 	8 	8 	Signed long integer
	//	unsigned char 	1 	1 	Unsigned small integer
}




